package cn.ljy.authority.config.security.sms;

import cn.ljy.authority.config.security.MySecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 短信验证码认证过滤器
 * 负责拦截特定的URL请求，提取手机号和验证码，并创建认证令牌进行身份验证。
 */
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public SmsCodeAuthenticationFilter() {
        //设置过滤器拦截的URL路径（如果不匹配则传递到下一个过滤器），只处理POST请求
        super(new AntPathRequestMatcher(MySecurityConfig.ADMINLOGINSMSURL, "POST"));
    }

    //执行实际的认证尝试,是手机验证码登录的起点
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        //1.获取从接口传递过来的手机号和验证码
        String tel = request.getParameter("tel");
        String code = request.getParameter("code");
        if (tel == null) {
            tel = "";
        }
        if (code == null) {
            code = "";
        }
        //2.创建认证令牌（此时还未验证），封装猴急和验证码，准备将其传到AuthenticationManager进行验证
        SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(tel, code);
        //3.将HTTP请求的详细信息（如参数、IP地址、Session ID等）添加到令牌中
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
        //4.认证任务委托给Spring Security的AuthenticationManager，
        // AuthenticationManager会找到支持SmsCodeAuthenticationToken的AuthenticationProvider进行实际认证
        return this.getAuthenticationManager().authenticate(authRequest);
    }

    //继承父类方法，用于设置认证成功的处理器
    @Override
    public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
        super.setAuthenticationSuccessHandler(successHandler);
    }

    //继承父类方法，用于设置认证失败的处理器
    @Override
    public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
        super.setAuthenticationFailureHandler(failureHandler);
    }
}

